package com.ksd.pug.thread.controller;

import com.ksd.pug.thread.pojo.SysUser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 飞哥B站地址：https://space.bilibili.com/490711252
 * 记得关注和三连哦！
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2022/2/25 15:47
 */
@RestController
@RequestMapping("/consumer")
@Slf4j
public class UserController {

    @Autowired
    private RestTemplate restTemplate;


    /**
     * 查询用户方法1
     * @param id
     * @return
     */
    @GetMapping("/user/{id}")
    @HystrixCommand(
            // fallback 容错降级方法
            fallbackMethod = "fallback",
            // 线程池的名称
            groupKey = "user-service-thread-01",
            // 执行的方法
            commandKey = "findUsers",
            // 对线程池的大小和线程开启参数设置
            threadPoolProperties = {
                    // 线程池的大小
                    @HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE, value = "30"),
                    // 最大队列长度
                    @HystrixProperty(name = HystrixPropertiesManager.MAX_QUEUE_SIZE, value = "100"),
                    // 线程存活时间
                    @HystrixProperty(name = HystrixPropertiesManager.KEEP_ALIVE_TIME_MINUTES, value = "2"),
                    // 拒绝请求
                    @HystrixProperty(name = HystrixPropertiesManager.QUEUE_SIZE_REJECTION_THRESHOLD, value = "15"),
            }
    )
    public SysUser findUsers(@PathVariable("id") Long id) {
        log.info("findusers");
        return restTemplate.postForObject("http://kuangstudy-hystrix-user-service/api/user/" + id, null, SysUser.class);
    }



    /**
     * 查询用户方法2
     * @param id
     * @return
     */
    @GetMapping("/user2/{id}")
    @HystrixCommand(
            // fallback 容错降级方法
            fallbackMethod = "fallback",
            // 线程池的名称
            groupKey = "user-service-thread-02",
            // 执行的方法
            commandKey = "findUsers2",
            // 对线程池的大小和线程开启参数设置
            threadPoolProperties = {
                // 线程池的大小, 官方标准：每秒最大支撑的请求数（99%）平均响应时间 + 一个缓冲值，比如：每秒能处理1000个请求，99%的请求响应时间是：60ms ，
                // 那么公式就是：400 * (0.06 + 0.012) = 20~
                /************************************************线程池配置参数***************************************/
                @HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE, value = "30"),
                // 最大队列长度 默认值一般是：-1 ,如果使用正数，队列将从同步队列转换成阻塞队列。从SynchronousQueue改成LinkedBlockingQueue
                @HystrixProperty(name = HystrixPropertiesManager.MAX_QUEUE_SIZE, value = "100"),
                // 线程存活时间 默认值是：1分钟，控制一个线程从使用到被释放的时间。
                @HystrixProperty(name = HystrixPropertiesManager.KEEP_ALIVE_TIME_MINUTES, value = "1"),
                // 拒绝请求 此属性不适合用于maxQueueSize=-1的情况，设置这个值得原因是maxQueueSize值运行时不能改变。我们可以修改这个变量动态修改允许排队的长度。
                @HystrixProperty(name = HystrixPropertiesManager.QUEUE_SIZE_REJECTION_THRESHOLD, value = "15"),
                /************************************************熔断参数************************************************/
                @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "20"),
                // 默认是：50% 当请求的错误率大于50%的时候就熔断，然后for循环发起请求，当请求符合熔断条件时讲触发getFallback()
                @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),
                // 默认是 5秒，熔断多少秒去尝试请求
                @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000")
            }
    )
    public SysUser findUsers2(@PathVariable("id") Long id) {
        log.info("findusers2");
        return restTemplate.postForObject("http://kuangstudy-hystrix-user-service/api/user/" + id, null, SysUser.class);
    }


    public SysUser fallback(Long id) {
        SysUser sysUser = new SysUser();
        sysUser.setId(-1L);
        return sysUser;
    }
}
